package cn.ekuma.data.ui.swing.dnd;

import javax.swing.JPanel;
import javax.swing.JSplitPane;
import java.awt.BorderLayout;
import java.awt.datatransfer.Transferable;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.awt.dnd.DropTargetListener;
import java.util.List;
import javax.swing.JLabel;
import java.awt.Dimension;
import javax.swing.border.TitledBorder;
import javax.swing.UIManager;
import java.awt.Color;
import java.awt.GridLayout;
import javax.swing.border.BevelBorder;
import javax.swing.border.EtchedBorder;

public abstract class AbstractJBeanDropPanel<K,T> extends JPanel{
     protected K bean;
	/**
	 * Create the panel.
	 */
	public AbstractJBeanDropPanel() {
		initComponents();
		DropTarget dropTarget = new DropTarget(dropSrc, // component to monitor
		        new SrcDropTargetListener()); // listener to notify
		
		DropTarget dropTarget1 = new DropTarget(dropDesp, // component to monitor
		        new DespDropTargetListener()); // listener to notify
		
		DropTarget dropTarget2 = new DropTarget(dropDespDrop, // component to monitor
		        new DespDropDeleteTargetListener()); // listener to notify
	}
	
	
	private void initComponents() {
		setLayout(new BorderLayout(0, 0));
		
		JSplitPane splitPane = new JSplitPane();
		splitPane.setResizeWeight(0.3);
		add(splitPane);
		
		dropSrc = new JLabel("      ");
		splitPane.setLeftComponent(dropSrc);
		setBorder(new TitledBorder(UIManager.getBorder("TitledBorder.border"), getDropTypeTitle(), TitledBorder.CENTER, TitledBorder.TOP, null, new Color(0, 70, 213)));
		setPreferredSize(new Dimension(149, 79));
		
		panel = new JPanel();
		panel.setLayout(new GridLayout(1, 2, 0, 0));
		
		dropDesp = new JLabel("        ");
		dropDesp.setBorder(new EtchedBorder(EtchedBorder.LOWERED, null, null));
		panel.add(dropDesp);
		
		dropDespDrop = new JLabel("*******");
		dropDespDrop.setBorder(new EtchedBorder(EtchedBorder.RAISED, null, null));
		panel.add(dropDespDrop);
		splitPane.setRightComponent(panel);
	}

	JLabel dropSrc;
	JLabel dropDesp;
	private JPanel panel;
	private JLabel dropDespDrop;
	
	public abstract void doDropInsert(List<T> beans);
	
	public abstract String readerBean(K obj);
	
	public abstract String getDropTypeTitle();
	
	public abstract void doDropDelete(List<T> dropList);
	
	class SrcDropTargetListener implements DropTargetListener{

		@Override
		public void dragEnter(DropTargetDragEvent dtde) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void dragOver(DropTargetDragEvent dtde) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void dropActionChanged(DropTargetDragEvent dtde) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void dragExit(DropTargetEvent dte) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void drop(DropTargetDropEvent e) {
			// First, check whether we understand the data that was dropped.
		    // If we supports our data flavors, accept the drop, otherwise reject.
		    if (e.isDataFlavorSupported(BeanTransferable.beanDataFlavor)) {
		      e.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
		    } else {
		      e.rejectDrop();
		      return;
		    }

		    // We've accepted the drop, so now we attempt to get the dropped data
		    // from the Transferable object.
		    Transferable t = e.getTransferable(); // Holds the dropped data

		    // First, try to get the data directly as a scribble object
		    try {
		    	bean = (K) t.getTransferData(BeanTransferable.beanDataFlavor);
		    } catch (Exception ex) { // unsupported flavor, IO exception, etc.
		        // If we still couldn't get the data, tell the system we failed
		        e.dropComplete(false);
		        return;
		    }
		    dropSrc.setText(readerBean(bean));
		    e.dropComplete(true); // signal success!
		}
	}
	
	class DespDropTargetListener implements DropTargetListener{

		@Override
		public void dragEnter(DropTargetDragEvent dtde) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void dragOver(DropTargetDragEvent dtde) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void dropActionChanged(DropTargetDragEvent dtde) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void dragExit(DropTargetEvent dte) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void drop(DropTargetDropEvent e) {
			if(bean==null){
				e.rejectDrop();
			    return;
			}
				
			// First, check whether we understand the data that was dropped.
		    // If we supports our data flavors, accept the drop, otherwise reject.
		    if (e.isDataFlavorSupported(BeanListTransferable.beanListDataFlavor)) {
		      e.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
		    } else {
		      e.rejectDrop();
		      return;
		    }
		    

		    // We've accepted the drop, so now we attempt to get the dropped data
		    // from the Transferable object.
		    Transferable t = e.getTransferable(); // Holds the dropped data

		    // First, try to get the data directly as a scribble object
		    try {
		    	List<T> dropList=(List<T>) t.getTransferData(BeanListTransferable.beanListDataFlavor);
		    	doDropInsert(dropList);
		    } catch (Exception ex) { // unsupported flavor, IO exception, etc.
		        // If we still couldn't get the data, tell the system we failed
		        e.dropComplete(false);
		        return;
		    }
		    e.dropComplete(true); // signal success!
			
		}
		
	}
	
	class DespDropDeleteTargetListener implements DropTargetListener{

		@Override
		public void dragEnter(DropTargetDragEvent dtde) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void dragOver(DropTargetDragEvent dtde) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void dropActionChanged(DropTargetDragEvent dtde) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void dragExit(DropTargetEvent dte) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void drop(DropTargetDropEvent e) {
			if(bean==null){
				e.rejectDrop();
			    return;
			}
				
			// First, check whether we understand the data that was dropped.
		    // If we supports our data flavors, accept the drop, otherwise reject.
		    if (e.isDataFlavorSupported(BeanListTransferable.beanListDataFlavor)) {
		      e.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
		    } else {
		      e.rejectDrop();
		      return;
		    }
		    

		    // We've accepted the drop, so now we attempt to get the dropped data
		    // from the Transferable object.
		    Transferable t = e.getTransferable(); // Holds the dropped data

		    // First, try to get the data directly as a scribble object
		    try {
		    	List<T> dropList=(List<T>) t.getTransferData(BeanListTransferable.beanListDataFlavor);
		    	doDropDelete(dropList);
		    } catch (Exception ex) { // unsupported flavor, IO exception, etc.
		        // If we still couldn't get the data, tell the system we failed
		        e.dropComplete(false);
		        return;
		    }
		    e.dropComplete(true); // signal success!
			
		}
		
	}

	public void setBean(K bean) {
		this.bean = bean;
		dropSrc.setText(readerBean(bean));
	}
}
